{
 "metadata": {},
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
  {
   "cells": [
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Python Imaging Library\n",
      "----------------------\n",
      "\n",
      "`(!)\u00a0see\u00a0also\u00a0[:Cookbook/Matplotlib/LoadImage]\u00a0to\u00a0load\u00a0a\u00a0PNG\u00a0image`\n",
      "\n",
      "Apply this patch to make PIL Image objects both export and consume the\n",
      "array interface (from Travis Oliphant):"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "Index: PIL/Image.py\n",
      "===================================================================\n",
      "--- PIL/Image.py\t(revision 358)\n",
      "+++ PIL/Image.py\t(working copy)\n",
      "@@ -187,6 +187,42 @@\n",
      " \n",
      " }\n",
      " \n",
      "+if sys.byteorder == 'little':\n",
      "+    _ENDIAN = '<'\n",
      "+else:\n",
      "+    _ENDIAN = '>'\n",
      "+\n",
      "+_MODE_CONV = {\n",
      "+\n",
      "+    # official modes\n",
      "+    \"1\": ('|b1', None),\n",
      "+    \"L\": ('|u1', None),\n",
      "+    \"I\": ('%si4' % _ENDIAN, None),\n",
      "+    \"F\": ('%sf4' % _ENDIAN, None),\n",
      "+    \"P\": ('|u1', None),\n",
      "+    \"RGB\": ('|u1', 3),\n",
      "+    \"RGBX\": ('|u1', 4),\n",
      "+    \"RGBA\": ('|u1', 4),\n",
      "+    \"CMYK\": ('|u1', 4),\n",
      "+    \"YCbCr\": ('|u1', 4),\n",
      "+\n",
      "+    # Experimental modes include I;16, I;16B, RGBa, BGR;15,\n",
      "+    # and BGR;24.  Use these modes only if you know exactly\n",
      "+    # what you're doing...\n",
      "+\n",
      "+}\n",
      "+\n",
      "+def _conv_type_shape(im):\n",
      "+    shape = im.size[::-1]\n",
      "+    typ, extra = _MODE_CONV[im.mode]\n",
      "+    if extra is None:\n",
      "+        return shape, typ\n",
      "+    else:\n",
      "+        return shape+(extra,), typ\n",
      "+\n",
      "+\n",
      "+\n",
      "+\n",
      " MODES = _MODEINFO.keys()\n",
      " MODES.sort()\n",
      " \n",
      "@@ -491,6 +527,22 @@\n",
      "         return string.join(data, \"\")\n",
      " \n",
      "     ##\n",
      "+    # Returns the array_interface dictionary\n",
      "+    #\n",
      "+    # @return A dictionary with keys 'shape', 'typestr', 'data'\n",
      "+\n",
      "+    def __get_array_interface__(self):\n",
      "+        new = {}\n",
      "+        shape, typestr = _conv_type_shape(self)\n",
      "+        new['shape'] = shape\n",
      "+        new['typestr'] = typestr\n",
      "+        new['data'] = self.tostring()\n",
      "+        return new\n",
      "+\n",
      "+    __array_interface__ = property(__get_array_interface__, None, doc=\"array interface\")\n",
      "+\n",
      "+\n",
      "+    ##\n",
      "     # Returns the image converted to an X11 bitmap.  This method\n",
      "     # only works for mode \"1\" images.\n",
      "     #\n",
      "@@ -1749,7 +1801,61 @@\n",
      " \n",
      "     return apply(fromstring, (mode, size, data, decoder_name, args))\n",
      " \n",
      "+\n",
      " ##\n",
      "+# (New in 1.1.6) Create an image memory from an object exporting\n",
      "+#  the array interface (using the buffer protocol). \n",
      "+#\n",
      "+#  If obj is not contiguous, then the tostring method is called\n",
      "+#  and frombuffer is used\n",
      "+#\n",
      "+# @param obj Object with array interface\n",
      "+# @param mode Mode to use (will be determined from type if None)\n",
      "+\n",
      "+def fromarray(obj, mode=None):\n",
      "+    arr = obj.__array_interface__\n",
      "+    shape = arr['shape']\n",
      "+    ndim = len(shape)\n",
      "+    try:\n",
      "+        strides = arr['strides']\n",
      "+    except KeyError:\n",
      "+        strides = None\n",
      "+    if mode is None:\n",
      "+        typestr = arr['typestr']\n",
      "+        if not (typestr[0] == '|' or typestr[0] == _ENDIAN or\n",
      "+                typestr[1:] not in ['u1', 'b1', 'i4', 'f4']):\n",
      "+            raise TypeError, \"cannot handle data-type\"\n",
      "+        typestr = typestr[:2]\n",
      "+        if typestr == 'i4':\n",
      "+            mode = 'I'\n",
      "+        elif typestr == 'f4':\n",
      "+            mode = 'F'\n",
      "+        elif typestr == 'b1':\n",
      "+            mode = '1'\n",
      "+        elif ndim == 2:\n",
      "+            mode = 'L'\n",
      "+        elif ndim == 3:\n",
      "+            mode = 'RGB'\n",
      "+        elif ndim == 4:\n",
      "+            mode = 'RGBA'\n",
      "+        else:\n",
      "+            raise TypeError, \"Do not understand data.\"\n",
      "+    ndmax = 4\n",
      "+    bad_dims=0\n",
      "+    if mode in ['1','L','I','P','F']:\n",
      "+        ndmax = 2\n",
      "+    elif mode == 'RGB':\n",
      "+        ndmax = 3\n",
      "+    if ndim > ndmax:\n",
      "+        raise ValueError, \"Too many dimensions.\"\n",
      "+\n",
      "+    size = shape[:2][::-1]\n",
      "+    if strides is not None:\n",
      "+        obj = obj.tostring()\n",
      "+        \n",
      "+    return frombuffer(mode, size, obj)\n",
      "+    \n",
      "+##\n",
      " # Opens and identifies the given image file.\n",
      " # <p>\n",
      " # This is a lazy operation; this function identifies the file, but the"
     ],
     "language": "python",
     "metadata": {},
     "outputs": []
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "### Exemple"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      ">>> import Image\n",
      ">>> im=Image.open('foo1.png')\n",
      ">>> a=numpy.array(p)\n",
      "# do something with a ...\n",
      ">>> im = Image.fromarray(a)\n",
      ">>> im.save( 'foo2.png' )"
     ],
     "language": "python",
     "metadata": {},
     "outputs": []
    }
   ],
   "metadata": {}
  }
 ]
}